package at.jku.pervasive.recognition;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * This {@link GesturePublisher} implementation publishes all gestures to all
 * listeners which listen on specific port.
 * @author clemens
 */
public class SocketGesturePublisher implements GesturePublisher
{

	private boolean isListening;
	private int port;
	private ServerSocket socket;
	private List<GesturePublisher> threads;

	public SocketGesturePublisher(int port)
	{
		super();

		this.threads = new LinkedList<GesturePublisher>();
		this.port = port;
	}

	public int getPort()
	{
		return port;
	}

	/**
	 * (non-Javadoc)
	 * @see at.jku.pervasive.recognition.GesturePublisher#startProducing()
	 */
	public void startProducing() throws IOException
	{
		this.socket = new ServerSocket(this.port);
		this.isListening = true;

		new Thread()
		{
			@Override
			public void run()
			{
				while (isListening)
				{
					try
					{
						Socket clientSocket = socket.accept();
						GesturePublisher gesturePublisher = new GesturePublisherThread(clientSocket);
						gesturePublisher.startProducing();
						threads.add(gesturePublisher);
					} catch (IOException ioEx)
					{
						throw new RuntimeException(ioEx);
					}
				}
			}
		}.start();
	}

	/**
	 * (non-Javadoc)
	 * @see at.jku.pervasive.recognition.GesturePublisher#stopProducing()
	 */
	public void stopProducing()
	{
		this.isListening = false;
		for (GesturePublisher gesturePublisher : threads)
		{
			gesturePublisher.stopProducing();
		}
	}

	@Override
	public void gestureFinished(GestureType gestureType, long duration)
	{
		for (GesturePublisher gesturePublisher : threads)
		{
			gesturePublisher.gestureFinished(gestureType, duration);
		}
	}

	@Override
	public void gestureStarted(GestureType gestureType, Date timestamp)
	{
		for (GesturePublisher gesturePublisher : threads)
		{
			gesturePublisher.gestureStarted(gestureType, timestamp);
		}
	}

}
